package naga.x.platform2.channel.s399.support;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

import com.alibaba.fastjson.JSONObject;

import naga.x.platform2.app.model.RechargeTemplate;
import naga.x.platform2.utils.CommonUtils;
import naga.x.platform2.utils.IOUtils;
import naga.x.platform2.utils.NumberUtils;
import naga.x.platform2.utils.StringUtils;
import naga.x.platform2.utils.UUID;

/**
 * 4399
 * @see doc/4399.html
 * @author yang.li
 *
 */
@Component
public class S399Api {

	@Autowired
	private S399Config config;
	
	public enum Code {
		SUCC(0, null),
		TIMEOUT(-1, "请求超时"),
		SIGN_ERROR(-2, "校验失败"),
		SERVER_NOT_FOUND(-3, "服务器id错误"),
		PLAYER_ID_ERROR(-4, "玩家id错误"),
		RECHARGE_PRODUCT_NOT_FOUND(-5, "充值id错误"),
		ORDER_DUPLICATED(-6, "订单重复"),
		SYSTEM_ERROR(-999, "系统错误")
		;
		public final int code;
		public final String msg;
		Code(int code, String msg) {
			this.code = code;
			this.msg = msg;
		}
	}
	
	public enum SDKCode {
		SUCC(1, null), // 成功，如果订单重复也直接返回1
		PARAMS_ERROR(-1, "参数错误"), // 失败，提交参数不全
		SIGN_ERROR(-2, "校验失败"), // 验证错误
		USER_NOT_FOUND(-3, "用户不存在"), // 用户不存在
		TIMEOUT(-4, "请求超时"), // 请求超时（为保证用户体验超过10秒请输出此代码）
		RECHARGE_RATIO_ERROR(-5, "充值比例异常"), // 充值比例异常（游戏币除以人民币 不等于兑换比率）
		IP_ILLEGAL(-6, "请求ip验证失败"), // 请求ip验证失败。（请限制充值请求的来源ip为：115.182.52.* ip段 及 113.107.149.212）
		GAME_SERVER_NOT_FOUND(-7, "服务器不存在"), // 要充值的服务器不存在(server参数不正确)
		MONEY_ERROR(-8, "充值金额异常"), // 充值金额异常（PC端可改金额，可能导致下单金额和支付金额不一致）
		UNKOWN_ERROR(-99, "未知错误"), // 其他原因导致的充值失败
		;
		final int code;
		final String msg;
		SDKCode(int code, String msg) {
			this.code = code;
			this.msg = msg;
		}
		
		@Override
		public String toString() {
			return String.valueOf(code);
		}
	}
	
	public static class PayInfo {
		public final int serverId;
		public final long playerId;
		public final int productId;
		public static final PayInfo EMPTY = new PayInfo(-1, -1, -1);
		public PayInfo(int serverId, long playerId, int productId) {
			this.serverId = serverId;
			this.playerId = playerId;
			this.productId = productId;
		}
	}
	
	public String makeSign(Map<String, String> params) {
		Map<String, String> tree = params instanceof TreeMap ? params : new TreeMap<String, String>(params);
		Set<Entry<String, String>> set = tree.entrySet();
		StringBuilder buf = new StringBuilder(128);
		for (Entry<String, String> entry : set) {
			String key = entry.getKey();
			String val = entry.getValue();
			val = CommonUtils.decodeURL(val, IOUtils.UTF8); // need decode the value
			buf.append(key).append('=').append(val != null ? val : "");
		}
		buf.append(config.getCallbackKey());
		return CommonUtils.md5(buf.toString());
	}
	
	public String createLoginRedirectUrl(Code code) {
		return createLoginRedirectUrl(code, null, null);
	}
	
	public String createLoginRedirectUrl(Code code, String userId, String userName) {
		StringBuilder buf = new StringBuilder(UrlBasedViewResolver.REDIRECT_URL_PREFIX);
		buf.append(config.getClientUrl()).append("&code=").append(code.code);
		if (code == Code.SUCC) {
			buf.append("&userid=").append(userId).append("&username=").append(CommonUtils.encodeURL(userName, IOUtils.UTF8)).append("&token=1");
		} else {
			buf.append("&msg=").append(CommonUtils.encodeURL(code.msg, IOUtils.UTF8));
		}
		return buf.toString();
	}
	
	public boolean isValidIp(String ip) {
		if (StringUtils.isEmpty(ip)) {
			return false;
		}
		String[] ips = config.getIpWhitelist();
		for (String _ip : ips) {
			if (ip.startsWith(_ip)) {
				return true;
			}
		}
		return false;
	}
	
	//---static---
	public static Object createOrderResponse(Code code) {
		return createOrderResponse(code, -1, -1, null);
	}
	
	public static Object createOrderResponse(Code code, int serverId, long playerId, RechargeTemplate product) {
		JSONObject res = new JSONObject(8, true);
		if (code == Code.SUCC) {
			res.put("code", code.code);
			res.put("money", product.getPrice()); // 充值金额（人民币：元） 只能为整数
			res.put("mark", UUID.randomUUID().toString()); // 游戏的充值订单编号 最多32位
			res.put("server", serverId); // 服务器编号 不能为空或者0
			res.put("extra", serverId + "|" + playerId + "|" + product.getId()); // 透传参数，用于充值成功后的服务端回调地址
		} else {
			res.put("code", code.code);
			res.put("msg", code.msg);
		}
		return res;
	}
	
	public static PayInfo parsePayInfo(String ext) {
		String[] strs = StringUtils.split(ext, "|");
		if (strs == null || strs.length != 3) {
			return PayInfo.EMPTY;
		}
		int serverId = NumberUtils.parseInt(strs[0]);
		long playerId = NumberUtils.parseLong(strs[1]);
		int productId = NumberUtils.parseInt(strs[2]);
		return new PayInfo(serverId, playerId, productId);
	}
	
	public static String valueFilter(Object value) {
		return value != null ? value.toString() : "";
	}
	//---static---
	
	
}
